import cv2
import numpy as np

# 提取出车道图像
img = cv2.imread("./img/up01.png")

# 将图像按照HLS方式进行提取，希望在高亮度部分将车道线提取出来。
hls = cv2.cvtColor(img,cv2.COLOR_BGR2HLS)

# 将HLS三层进行分割
channel_h = hls[:,:,0] # 颜色 0 - 120 红 120 - 240 绿 240 - 360 蓝色
channel_l = hls[:,:,1] #
channel_s = hls[:,:,2]

# HLS 三层效果
# cv2.imshow("h",channel_h)
# cv2.imshow("l",channel_l)
# cv2.imshow("s",channel_s)
# cv2.waitKey(0)

# 利用sobel计算x方向的梯度
# 通过Sobel边缘算子进行横向边缘检测。
# 原因，因为车道本身是纵向的，如果用纵向检测，那就会失去掉这些边缘信息。
# sobel_x 所有检测出来的边缘信息
sobel_x = cv2.Sobel(channel_l,-1,1,0)
# 防止负数的边缘信息出现
abs_sobel_x = np.absolute(sobel_x)

# print(abs_sobel_x.shape)
# cv2.imshow("sobel",abs_sobel_x)
# cv2.waitKey(0)

# 由于Sobel算子将一些重要的高亮度区域忽略掉，手动将低亮度区域调高。（127 -> 255）
# Sobel中某些算子的大小超出了255，对原本图像进行压制（确保每个像素都在0-255）
scaled_sobel = np.uint8(abs_sobel_x / np.max(abs_sobel_x) * 255)

# cv2.imshow("sobel",scaled_sobel)
# cv2.waitKey(0)

# 将高亮区域提取出来
sx_binary = np.zeros_like(scaled_sobel)
# 将图像中的高亮像素（> 170 且 <= 255）提取出来
h,w = scaled_sobel.shape
for i in range(h):
    for j in range(w):
        if 170 < scaled_sobel[i][j] <= 255:
            sx_binary[i][j] = 255

# cv2.imshow("sx_binary",sx_binary)
# cv2.waitKey(0)

# 将饱和度较高的区域提取出来
s_binary = np.zeros_like(channel_s)
# 将图像中饱和度较高（> 100 且 <= 255）的部分提取出来
h,w = channel_s.shape
for i in range(h):
    for j in range(w):
        if 100 < channel_s[i][j] <= 255:
            s_binary[i][j] = 255

# cv2.imshow("s_binary",s_binary)
# cv2.waitKey(0)

# 将高亮区域与饱和度较高的区域进行融合
color_binary = (sx_binary | s_binary)
cv2.imshow("color_binary",color_binary)
cv2.waitKey(0)